package com.scorpio.agentuser.service.impl;

import com.github.pagehelper.PageHelper;
import com.scorpio.agentuser.domain.AgentUserEntity;
import com.scorpio.agentuser.dto.AgentUserDTO;
import com.scorpio.agentuser.enums.AgentLevelEnum;
import com.scorpio.agentuser.mapper.AgentUserMapper;
import com.scorpio.agentuser.service.AgentUserService;
import com.scorpio.agentuser.vo.*;
import com.scorpio.common.annotation.DataSource;
import com.scorpio.common.constant.Constants;
import com.scorpio.common.enums.DataSourceType;
import com.scorpio.common.exception.CustomException;
import com.scorpio.common.service.impl.BaseServiceImpl;
import com.scorpio.common.utils.ConvertUtils;
import com.scorpio.common.utils.MathUtil;
import com.scorpio.common.utils.StringUtils;
import com.scorpio.common.utils.security.SecurityUtils;
import com.scorpio.redis.cachelock.RedisLock;
import com.scorpio.redis.constant.RedisConstants;
import com.scorpio.system.service.ISysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

@Service
@DataSource(DataSourceType.SLAVE)
public class AgentUserServiceImpl extends BaseServiceImpl<AgentUserMapper, AgentUserEntity> implements AgentUserService {

    @Autowired
    private RedisLock redisLock;

    @Autowired
    private ISysConfigService configService;

    @Override
    public AgentUserEntity selectById(Long agentId) {
        return baseDao.selectById(agentId);
    }

    @Override
    public AgentUserDTO selectDetailsById(Long agentId) {
        return baseDao.selectDetailsById(agentId);
    }

    @Override
    public AgentUserEntity selectByPhone(String phone) {
        PageHelper.startPage(1, 1, "create_time desc");
        AgentUserEntity entity = baseDao.selectOne(
                getQueryWrapper().eq("phone", phone)
                        .eq("status", 0));
        return entity;
    }

    @Override
    public AgentUserEntity selectByUsername(String username) {
        PageHelper.startPage(1, 1, "create_time desc");
        AgentUserEntity entity = baseDao.selectOne(
                getQueryWrapper().eq("username", username)
                        .eq("status", 0));
        return entity;
    }

    @Override
    @Transactional
    public int createUser(AgentUserEntity entity, CreateUserVo vo) {
        if (entity.getAgentLevel() != AgentLevelEnum.Level_1.getType()
                && entity.getAgentLevel() != AgentLevelEnum.Level_2.getType()
                && entity.getAgentLevel() != AgentLevelEnum.Level_3.getType()) {
            throw new CustomException("无操作权限");
        }
        String lockKey = RedisConstants.SYS_LOCK_KEY + "createUser:" + entity.getInviteCode();
        int nextLevel = entity.getAgentLevel() + 1;
        try {
            if (!redisLock.lock(lockKey, 3)) {
                throw new CustomException("请稍后再试");
            }
            AgentUserEntity nEntity = ConvertUtils.sourceToTarget(vo, AgentUserEntity.class);
            return createUser(nEntity, nextLevel, entity.getChain(), entity.getId(), vo.getPassword());
        } finally {
            redisLock.unlock(lockKey);
        }
    }

    @Override
    public int updateUser(UpdateUserVo vo) {
        return baseDao.updateInfo(vo);
    }

    @Override
    public int updatePassword(AgentUserEntity entity, UpdatePasswordVo vo) {
        entity = baseDao.selectById(entity.getId());
        if (!SecurityUtils.matchesPassword(vo.getOldPassword(), entity.getPassword())) {
            throw new CustomException("原密码不正确");
        } else if (SecurityUtils.matchesPassword(vo.getNewPassword(), entity.getPassword())) {
            throw new CustomException("新密码不能与旧密码相同");
        }
        int count = baseDao.updatePassword(entity.getId(), SecurityUtils.encryptPassword(vo.getNewPassword()));
        return count;
    }

    @Override
    public int updateIncomeScale(AgentUserEntity entity, UpdateIncomeScaleVo vo) {
        AgentUserEntity agent = selectById(vo.getAgentId());
        if (agent == null) {
            throw new CustomException("用户不存在或已删除");
        }
        if (!entity.getId().equals(agent.getPid())) {
            throw new CustomException("只能编辑本人下级的代理商");
        }
        float directScale = MathUtil.fromDecimaToFloat(vo.getDirectScale(), 2);
        float indirectScale = MathUtil.fromDecimaToFloat(vo.getIndirectScale(), 2);
        return baseDao.updateIncomeScale(agent.getId(), directScale, indirectScale);
    }

    @Override
    public List<AgentUserDTO> lowerUserList(AgentUserEntity entity) {
        return baseDao.lowerList(entity.getId());
    }

    @Override
    public int resetAgentPwd(Long agentId, String password) {
        return baseDao.updatePassword(agentId, SecurityUtils.encryptPassword(password));
    }


    /**
     * 查询代理商用户
     *
     * @param remark 代理商用户ID
     * @return 代理商用户
     */
    @Override
    public AgentUserEntity selectById(String remark) {
        return baseDao.selectById(remark);
    }

    /**
     * 查询代理商用户列表
     *
     * @param entity 代理商用户
     * @return 代理商用户
     */
    @Override
    public List<AgentUserEntity> selectList(AgentUserEntity entity) {
        return baseDao.list(entity);
    }

    /**
     * 新增代理商用户
     *
     * @param vo 代理商用户
     * @return 结果
     */
    @Override
    public int save(CreateUpdateUserVo vo) {
        vo.setId(null);
        int nextLevel = AgentLevelEnum.Level_1.getType();
        AgentUserEntity entity = ConvertUtils.sourceToTarget(vo, AgentUserEntity.class);
        String initPassword = configService.selectConfigByKey(Constants.initPassword);
        initPassword = StringUtils.isEmpty(initPassword) ? "123456" : initPassword;
        return createUser(entity, nextLevel, "", 0, initPassword);
    }

    /**
     * 修改代理商用户
     *
     * @param vo 代理商用户
     * @return 结果
     */
    @Override
    public int update(CreateUpdateUserVo vo) {
        return baseDao.updateInfo2(vo);
    }

    /**
     * 批量删除代理商用户
     *
     * @param remarks 需要删除的代理商用户ID
     * @return 结果
     */
    @Override
    public int deleteByIds(String[] remarks) {
        return baseDao.deleteBatchIds(Arrays.asList(remarks));
    }

    /**
     * 删除代理商用户信息
     *
     * @param remark 代理商用户ID
     * @return 结果
     */
    @Override
    public int deleteById(String remark) {
        return baseDao.deleteById(remark);
    }


    /**
     * 创建用户操作
     *
     * @param entity    新用户实体
     * @param nextLevel 等级
     * @param chain
     * @param pid
     * @param password
     * @return
     */
    private int createUser(AgentUserEntity entity, int nextLevel, String chain, long pid, String password) {
        if (baseDao.selectCount(getQueryWrapper().eq("username", entity.getUsername())) > 0) {
            throw new CustomException("该帐号已存在");
        }
        String icode = MathUtil.getRandLetter(8);
        int rundCount = 0;
        while (true) {
            //判定数据库是否有重复
            if (baseDao.selectCount(getQueryWrapper().eq("invite_code", icode)) > 0) {
                icode = MathUtil.getRandLetter(8);
                if (rundCount > 10) {
                    throw new CustomException("请稍后再试");
                }
                rundCount++;
                continue;
            }
            break;
        }
        if (pid == 0) {
            entity.setChain("");
        } else if (StringUtils.isEmpty(chain)) {
            entity.setChain(pid + ",");
        } else {
            entity.setChain(chain + pid + ",");
        }
        entity.setPid(pid);
        entity.setInviteCode(icode);
        entity.setPassword(SecurityUtils.encryptPassword(password));
        entity.setAgentLevel(nextLevel);
        return baseDao.insert(entity);
    }


}
